package xin.shaozeming.base.common.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.log4j.Log4j2;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Date;
import java.util.List;


/**
 * @author: 邵泽铭
 * @date: 2019/7/17
 * @description:
 **/
@Log4j2
public class ParamUtils {


    public static <O> Page<O> getPage(String page, String size, String sortParam, String direction,boolean isOrder){

        Page<O> p = new Page<>();
        p.setCurrent(new Integer(page));
        p.setSize(new Integer(size));
        if(isOrder){
            if (!StringUtils.isEmpty(sortParam) && !StringUtils.isEmpty(direction)) {
                if (new Integer(direction) == 1) {
                    p.setAsc(sortParam);
                } else {
                    p.setDesc(sortParam);
                }
            } else {
                p.setDesc("id");
            }
        }

        return p;
    }

    public static  <O> O parseEnityParam( String className,String param){
        try {

            Object object=  Class.forName(className).newInstance();
            O  t=(O)object;
            if(StringUtils.isEmpty(param)){
                return  t;
            }
            JSONObject jsonObject=JSONObject.parseObject(param);

            Method[] methods=  t.getClass().getDeclaredMethods();
            for (Method method:methods){
                String methodName=method.getName().substring(method.getName().lastIndexOf(".")+1,method.getName().length());
                if(methodName.startsWith("set")){
                    String field=methodName.substring(3,methodName.length());
                    if(field.length()>1){
                        field=field.substring(0,1).toLowerCase()+field.substring(1,field.length());
                    }
                    Class<?> aClass = method.getParameterTypes()[0];
                    /*包含TableName注解的是实体类*/
                    if(aClass.getAnnotation(TableName.class)!=null){
                        JSONObject entityObj= jsonObject.getJSONObject(field);
                        if(entityObj!=null){
                            Object res= parseEnityParam(aClass.getName(),JSONObject.toJSONString(entityObj));
                            method.invoke(t,res);
                        }
                    }
                    else if("java.lang.Integer".equals(aClass.getName())){
                        method.invoke(t,jsonObject.getInteger(field));
                    }else if("java.lang.String".equals(aClass.getName())){
                        method.invoke(t, jsonObject.getString(field));
                    }
                    else if("java.math.BigDecimal".equals(aClass.getName())){
                        method.invoke(t,jsonObject.getBigDecimal(field));
                    }
                    else if("java.lang.Boolean".equals(aClass.getName())){
                        method.invoke(t, jsonObject.getBoolean(field));
                    }
                    else if("java.util.Date".equals(aClass.getName())){
                        Date date= jsonObject.getDate(field);
                        method.invoke(t,date);

                    } else if("java.lang.Long".equals(aClass.getName())){
                        method.invoke(t,jsonObject.getLong(field));
                    } else if("java.util.List".equals(aClass.getName())){
                        /*获取list中的泛型*/
                        Type listClz=((ParameterizedType)t.getClass().getDeclaredField(field).getGenericType()).getActualTypeArguments()[0];
                        String listClassName= listClz.getTypeName();

                        JSONArray jsonArray= jsonObject.getJSONArray(field);
                        Object[] objArray=new Object[jsonArray.size()];

                        for(int i=0;i<jsonArray.size();i++){
                            objArray[i]=parseEnityParam(listClassName,JSONObject.toJSONString(jsonArray.getJSONObject(i)));
                        }

                        method.invoke(t,Arrays.asList(objArray));
                     }else {
                        log.error("parseEnityParam中未定义的类型：{}",aClass.getName());
                    }
                }
            }

            return  t;

        } catch (Exception e) {
            log.error("parseEnityParam中解析失败，错误：{}",e.getMessage());
            return  null;
        }

    }
    public static  <T> QueryWrapper<T> getWrapper(T t){
        if(t==null)
            return new QueryWrapper<>();
        QueryWrapper<T> queryWrapper=new QueryWrapper<>();
        Method[] methods= t.getClass().getDeclaredMethods();
        for (Method method:methods) {
            String methodName = method.getName().substring(method.getName().lastIndexOf(".") + 1, method.getName().length());
            if (methodName.startsWith("get")) {
                try {
                    Object obj= method.invoke(t);
                    if(!StringUtils.isEmpty(obj)){
                        String column=methodName.substring(3,methodName.length());
                        column=WordUtils.trans(column);
                        if("java.lang.String".equals(obj.getClass().getName())){
                            queryWrapper.like(column,obj);
                        }else {
                            queryWrapper.eq(column,obj);
                        }
                    }
                } catch (Exception e) {
                    log.error("生成queryWrapper错误-getWrapper,错误:{}",e.getMessage());
                    continue;
                }
            }
        }

        return queryWrapper;
    }

    public static  <T> QueryWrapper<T> getParamWrapper(String className,String param){
        if(StringUtils.isEmpty(param)){
            return new QueryWrapper<>();
        }
        JSONObject jsonObject =null;
        Class<?> aClass=null;
        try {
        aClass=Class.forName(className);
        if(aClass==null)
            return new QueryWrapper<>();

            jsonObject = JSONObject.parseObject(param);
        } catch (Exception e) {
            log.error("queryWrapper反射错误,错误:{}",e.getMessage());
            e.printStackTrace();
        }
        if(jsonObject==null){
            return  new QueryWrapper<>();
        }
        QueryWrapper<T> queryWrapper=new QueryWrapper<>();
        Method[] methods= aClass.getDeclaredMethods();
        for (Method method:methods) {
            String methodName = method.getName().substring(method.getName().lastIndexOf(".") + 1, method.getName().length());
            if (methodName.startsWith("get")) {
                try {
                    String field=methodName.substring(3,methodName.length());
                    if(field.length()>1){
                        field=field.substring(0,1).toLowerCase()+field.substring(1,field.length());
                    }
                    Object obj= jsonObject.get(field);
                    if(!StringUtils.isEmpty(obj)){
                         String rsClass=  method.getReturnType().getName();
                        String column=methodName.substring(3,methodName.length());
                        column=WordUtils.trans(column);
                        if("java.lang.String".equals(rsClass)){
                            queryWrapper.like(column,obj.toString());
                        }else if("java.util.Date".equals(rsClass)){
                            if(obj instanceof JSONArray){
                                JSONArray jsonArray=(JSONArray)obj;
                                if(jsonArray.size()<=1){
                                    queryWrapper.eq(column,DateUtils.parseToDate(obj.toString()));
                                    continue;
                                }
                                 Date start=jsonArray.getDate(0);
                                 Date end=jsonArray.getDate(1);

                                 if((start!=null&&end!=null)&&start.equals(end)){
                                     queryWrapper.eq(column,DateUtils.parseToDate(obj.toString()));
                                     continue;
                                 }
                                 if (start!=null){
                                     queryWrapper.ge(column, start);
                                 }
                                if (end!=null){
                                    queryWrapper.le(column, DateUtils.addDate(end, 1));
                                }
                            }else {
                                queryWrapper.eq(column,DateUtils.parseToDate(obj.toString()));
                            }
                        }else {
                            //枚举
                            if(method.getReturnType().getEnumConstants()!=null){
                                String[] enums=obj.toString().split("\\|\\|");
                                if(enums.length==0){
                                    continue;
                                }
                                if(enums.length==1){
                                    queryWrapper.eq(column,enums[0]);
                                }
                                if(enums.length>1){

                                    String finalColumn = column;
                                    queryWrapper.and(andWrapper->{
                                        for (String anEnum : enums) {
                                            andWrapper.eq(finalColumn, anEnum);
                                            andWrapper.or();
                                        }

                                        return andWrapper;
                                    });

                                }
                            }else {
                                queryWrapper.eq(column,obj);
                            }

                        }
                    }
                } catch (Exception e) {
                    log.error("生成queryWrapper错误,错误:{}",e.getMessage());
                    continue;
                }
            }
        }

        return queryWrapper;
    }

    public static   <O> void parseDecideSaveOrUpdate(Class<?> aClass,O o){
        try {
            Method getId = aClass.getDeclaredMethod("getId");
            Object obj = getId.invoke(o);
            if (obj == null) {
                Method createdTime = o.getClass().getDeclaredMethod("setCreatedTime", Date.class);
                if(createdTime!=null){
                    createdTime.invoke(o, new Date());
                }
            }
            Method modifiedTime = o.getClass().getDeclaredMethod("setModifiedTime", Date.class);
            if(modifiedTime!=null){
                modifiedTime.invoke(o,new Date());
            }
        } catch (Exception e) {
            log.error("parseDecideSaveOrUpdate判断保存或更新异常,错误:{}",e.getMessage());
        }
    }

    public   static <O,T> Page<O>   convertPage(IPage<T> tPage,List<O> list ){
        return new Page<O>(tPage.getCurrent(),tPage.getSize(),tPage.getTotal()).setRecords(list);
    }


    public static void main(String[] args) throws Exception {



    }
}
